package com.moneywelcome.userserviceassembly.controller;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.generator.SnowflakeGenerator;
import com.alibaba.fastjson.JSONObject;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.moneywelcome.api.RiskApi;
import com.moneywelcome.dto.RiskResult;
import com.moneywelcome.exceptions.MwcArgsException;
import com.moneywelcome.http.ServletUtil;
import com.moneywelcome.jwt.JWTHelper;
import com.moneywelcome.results.Result;
import com.moneywelcome.results.StatusCode;
import com.moneywelcome.userserviceassembly.entity.UserInfo;
import com.moneywelcome.userserviceassembly.entity.UserLogin;
import com.moneywelcome.userserviceassembly.exception.UserRegisterExecption;
import com.moneywelcome.userserviceassembly.service.UserInfoService;
import com.moneywelcome.userserviceassembly.service.UserService;
import com.moneywelcome.userserviceassembly.util.GetIp;
import com.moneywelcome.validate.ValidationUtils;
import com.moneywelcome.vo.RiskVo;
import com.woniu.demo.Api.UserApi;
import com.woniu.demo.Dto.PageDto;
import com.woniu.demo.Dto.UpdatePasswordDto;
import com.woniu.demo.Dto.UserInfoDto;
import com.woniu.demo.Dto.UserLoginDto;
import com.woniu.demo.param.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@Api(tags = "用户登录注册基本信息管理接口")
public class UserController implements UserApi {

    @Resource
    private UserService userLoginService;

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private StringRedisTemplate srt;

    @Resource
    private JWTHelper jwtHelper;
    @Resource
    private RiskApi riskApi;

    //账号注册
    @Override
    @ApiOperation("手机号注册")
    public Result register(PhoneRegisterParam phoneRegisterParam ) {
       //参数校验
        ValidationUtils.validate(phoneRegisterParam);
        //密码不能为空
        if(phoneRegisterParam.getPassword()==null||phoneRegisterParam.getPassword()==""){
            throw new UserRegisterExecption(10040,"密码不能为空");
        }
        QueryWrapper<UserLogin> qw = new QueryWrapper();
        qw.eq("phone",phoneRegisterParam.getUserPhone());
        //查看是否已经注册
        UserLogin user = userLoginService.getOne(qw);
        if (user!=null) throw new UserRegisterExecption(10041,"该电话号码已经注册");
        //发送验证码
        userLoginService.phonesetcode(phoneRegisterParam.getUserPhone());
        //验证码校验
        Result checkcode = userLoginService.checkcode(phoneRegisterParam);
        //验证码通过后存入数据库，添加账号，密码一次加密
        if (checkcode.getCode()!=null){
            UserLogin userLogin = new UserLogin();
            //设置账户和手机号，账户默认是手机号
            userLogin.setAccount(phoneRegisterParam.getUserPhone());
            userLogin.setPhone(phoneRegisterParam.getUserPhone());
            userLogin.setPassword(DigestUtil.md5Hex(phoneRegisterParam.getPassword()));
            //设置日期格式
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //设置注册时间
            userLogin.setRegisterTime(df.format(new Date()));
            //设置状态
            userLogin.setAccountStatus(0);
            //设置上次登陆时间
            userLogin.setLastLoginTime("无");
            //设置ip
            HttpServletRequest httpServletRequest = ServletUtil.getHttpServletRequest();
            String ipAddr = GetIp.getIpAddr(httpServletRequest);
            userLogin.setLastLoginIp(ipAddr);
            //存入数据库
            if (userLoginService.save(userLogin)) {
                return Result.success();
            }
        }
        return Result.fail();
    }
    @Override
    //手机号发送验证码
    @ApiOperation("手机号发送验证码接口")
    public Result phonesetcode(String phone){
        Result phonesetcode = userLoginService.phonesetcode(phone);
        return Result.success("200","验证码是",phonesetcode.getCode());
    }
    @Override
    //账号密码登录
    @ApiOperation("账号密码登录")
    public Result accLogin(UserAccountLoginParam userAccountLoginParam) {
        //参数校验
        ValidationUtils.validate(userAccountLoginParam);
        log.info("账号密码登录");
        //对登录密码进行加密
        userAccountLoginParam.setUserPassword(DigestUtil.md5Hex(userAccountLoginParam.getUserPassword()));;
        UserLoginDto userLoginDto = userLoginService.userLogin(userAccountLoginParam);
        //如果登录返回dto不为空
        if (userLoginDto!=null){
            //登录成功生成jwt，payload存login_id
            Date date = DateUtils.addDays(new Date(), 1);
            Map<String, Object> payload = new HashMap<>();
            //查出userId
            QueryWrapper<UserLogin> qw = new QueryWrapper();
            qw.eq("phone",userAccountLoginParam.getUserAccount());
            UserLogin user = userLoginService.getOne(qw);
            payload.put("user_id",user.getUserId());
            String jwt = jwtHelper.createJWT(date, payload);
            ServletUtil.getHttpServletResponse().addHeader("Authorization",jwt);

        return Result.success("200","登陆成功",jwt);
        }
        //登录失败
        return Result.fail();
    }
    @Override//手机短信验证码登录
    @ApiOperation("验证码登录接口")
    public Result<RiskResult> phoneLogin(PhoneLoginParam phoneLoginParam) {

        System.out.println(phoneLoginParam);
        //判断电话号码有没有注册
        UserLogin phone = userLoginService.getOne(new QueryWrapper<UserLogin>().eq("phone", phoneLoginParam.getUserPhone()));
        if (phone==null) return Result.fail("电话号码没有注册");
        String code = srt.opsForValue().get("woniu:demo:phone:"+phoneLoginParam.getUserPhone());
        System.out.println(code);
        //判断验证码存不存在
        if (code==null) return Result.fail("验证码不存在");
        //判断验证码正不正确
        if (!code.equals(phoneLoginParam.getUserCode())) return Result.fail("验证码错误");
        srt.delete("woniu:demo:phone:"+phoneLoginParam.getUserPhone());
        //查询该手机号有没有昵称，有的话就返回result
        //登录成功生成jwt，payload存login_id
        Date date = DateUtils.addDays(new Date(), 1);
        Map<String, Object> payload = new HashMap<>();
        //查出userId,存入payload
        QueryWrapper<UserLogin> qw = new QueryWrapper();
        qw.eq("phone",phoneLoginParam.getUserPhone());
        UserLogin user = userLoginService.getOne(qw);
        //风控调用
        HttpServletRequest httpServletRequest = ServletUtil.getHttpServletRequest();
        String ipAddr = GetIp.getIpAddr(httpServletRequest);
        RiskVo riskVo = new RiskVo();
        JSONObject jsonInfo = new JSONObject();
        jsonInfo.put("loginTime", DateUtil.current());
        jsonInfo.put("userId",user.getUserId());
        jsonInfo.put("eventId",new SnowflakeGenerator().next());
        jsonInfo.put("mobile",phoneLoginParam.getUserPhone());
        jsonInfo.put("userIP",ipAddr);
        jsonInfo.put("authcode",phoneLoginParam.getUserCode());
        riskVo.setJsonInfo(jsonInfo);
        riskVo.setModelName("login");
        log.info("{}",riskVo);
        RiskResult riskResult = riskApi.uoloadInfo(riskVo).getData();
        if("reject".equals(riskResult.getActivations().getRisk())) throw new MwcArgsException(riskResult.getHitsDetail().getDesc(), StatusCode.Error);
        //jwt
        payload.put("user_id",user.getUserId());
        String jwt = jwtHelper.createJWT(date, payload);
        ServletUtil.getHttpServletResponse().addHeader("Authorization",jwt);
        Result result = userLoginService.loadUserRoleNickname(phoneLoginParam.getUserPhone());

        userLoginService.update(new UpdateWrapper<UserLogin>().eq("user_id",user.getUserId())
                .set("last_login_ip", ipAddr));
        //返回jwt和用户信息
        return Result.success("200","登录成功",result);
    }

    @Override//删除用户
    @ApiOperation("删除账号信息接口")
    public Result remUser(List<Integer> ids) {
        if (userLoginService.remUser(ids)) {
            return Result.success("删除成功");
        }
        return Result.fail("删除失败");
    }


    @Override//修改用户信息,前台传入信息，后台存入实名验证信息
    @ApiOperation("完善基本信息接口")
    public Result updateUser(UpdateUserParam updateUserParam) {
        ValidationUtils.validate(updateUserParam);
        UserInfo userInfo = new UserInfo();
        BeanUtils.copyProperties(updateUserParam,userInfo);
        return Result.success();
    }

    @Override//查询用户，分页，模糊查询
    @ApiOperation("分页多条件查询账号信息接口")
    public Result selUser(PageFindUserParam pageFindUserParam) {
        PageDto user = userLoginService.findUser(pageFindUserParam);
        if (user!=null){
            return Result.success("200","查询成功",user);
        }
            return Result.fail("查询失败");
    }

    @Override
    public Result updateUser(UpdatePasswordParam updatePasswordParam) {
        UpdatePasswordDto updatePasswordDto = userLoginService.updateUserInfo(updatePasswordParam);
        if (updatePasswordDto!=null){
            return Result.success("200","修改成功",updatePasswordDto);
        }
        return Result.fail("修改失败");
    }

    //查询用户个人信息
    @Override
    public Result<UserInfoDto> selUserinfo(Integer userId) {
        UserInfoDto userInfo = userInfoService.findUserInfo(userId);
        if (userInfo==null){
            return Result.fail("查询失败");
        }
        return Result.success("200","查询成功",userInfo);
    }
}
